host = "8.137.20.68:443"

function generateRandomString() {
    const chars = '0123456789';
    let randomString = '';
    for (let i = 0; i < 3; i++) {
        const randomIndex = Math.floor(Math.random() * chars.length);
        randomString += chars.charAt(randomIndex);
    }
    return randomString;
}

let username = generateRandomString();
let localVideo = document.getElementById('localVideo');
let remoteVideo = document.getElementById('remoteVideo');
let websocket = null;
let peer = null;

function WebSocketInit() {
    if ('WebSocket' in window) {
        console.log(username);
        alert(username);
        websocket = new WebSocket("wss://" + host + "/Web/WebRtcWSServer?username=" + username);
    } else {
        alert("当前浏览器不支持WebSocket！");
    }

    websocket.onerror = function (e) {
        alert("WebSocket连接发生错误！");
    };

    websocket.onclose = function () {
        console.error("WebSocket连接关闭");
    };

    websocket.onopen = function () {
        console.log("WebSocket连接成功");
    };

    websocket.onmessage = async function (event) {
        let data = JSON.parse(event.data.replace(/\n/g, "\\n").replace(/\r/g, "\\r"));
        let { type, fromUser, msg, sdp, sdpMid, sdpMLineIndex, candidate } = data;

        console.log(type);

        if (type === 'hangup') {
            console.log(msg);
            document.getElementById('hangup').click();
            return;
        }

        if (type === 'call_start') {
            let msg = "0";
            if (confirm(fromUser + "发起屏幕共享，确定接听吗") == true) {
                document.getElementById('toUser').value = fromUser;
                WebRTCInit();
                msg = "1";
            }
            websocket.send(JSON.stringify({
                type: "call_back",
                toUser: fromUser,
                fromUser: username,
                msg: msg
            }));
            return;
        }

        if (type === 'call_back') {
            if (msg === "1") {
                console.log(document.getElementById('toUser').value + "同意屏幕共享");
                let stream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
                localVideo.srcObject = stream;
                stream.getTracks().forEach(track => {
                    peer.addTrack(track, stream);
                });
                let offer = await peer.createOffer();
                await peer.setLocalDescription(offer);
                offer.fromUser = username;
                offer.toUser = document.getElementById('toUser').value;
                websocket.send(JSON.stringify(offer));
            } else if (msg === "0") {
                alert(document.getElementById('toUser').value + "拒绝屏幕共享");
                document.getElementById('hangup').click();
            } else {
                alert(msg);
                document.getElementById('hangup').click();
            }
        }

        if (type === 'offer') {
            let stream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
            localVideo.srcObject = stream;
            stream.getTracks().forEach(track => {
                peer.addTrack(track, stream);
            });
            await peer.setRemoteDescription(new RTCSessionDescription({ type, sdp }));
            let answer = await peer.createAnswer();
            await peer.setLocalDescription(answer);
            let newAnswer = {
                type: 'answer',
                sdp: peer.localDescription.sdp,
                fromUser: username,
                toUser: document.getElementById('toUser').value
            };
            websocket.send(JSON.stringify(newAnswer));
            return;
        }

        if (type === 'answer') {
            await peer.setRemoteDescription(new RTCSessionDescription({ type, sdp }));
            handleIceCandidates();
            return;
        }

        if (type === '_ice') {
            // 处理候选参数可能为null的情况
            const iceCandidate = {
                candidate: candidate,
                sdpMid: sdpMid || null,
                sdpMLineIndex: sdpMLineIndex || 0
            };
            try {
                const rtcCandidate = new RTCIceCandidate(iceCandidate);
                if (peer.remoteDescription) {
                    await peer.addIceCandidate(rtcCandidate);
                } else {
                    iceCandidatesBuffer.push(rtcCandidate);
                }
            } catch (e) {
                console.error("Error adding ICE candidate:", e);
            }
            return;
        }
    }
}

let iceCandidatesBuffer = [];

function handleIceCandidates() {
    iceCandidatesBuffer.forEach(async (candidate) => {
        try {
            await peer.addIceCandidate(candidate);
        } catch (e) {
            console.error("Error adding buffered ICE candidate:", e);
        }
    });
    iceCandidatesBuffer = [];
}

WebSocketInit();
ButtonFunInit();

function WebRTCInit() {
    const iceServers = [
        { urls: "stun:117.50.221.81:3478" },
        {
            urls: "turn:117.50.221.81:3478",
            username: "username",
            credential: "password"
        }
    ];

    peer = new RTCPeerConnection({ iceServers });

    peer.onicecandidate = function (e) {
        if (e.candidate) {
            // 确保发送所有必要字段
            websocket.send(JSON.stringify({
                type: '_ice',
                toUser: document.getElementById('toUser').value,
                fromUser: username,
                sdpMid: e.candidate.sdpMid,
                sdpMLineIndex: e.candidate.sdpMLineIndex,
                candidate: e.candidate.candidate
            }));
        }
    };

    peer.ontrack = function (e) {
        if (e && e.streams) {
            remoteVideo.srcObject = e.streams[0];
        }
    };
}

function ButtonFunInit() {
    document.getElementById('call').onclick = function (e) {
        document.getElementById('toUser').style.visibility = 'hidden';
        let toUser = document.getElementById('toUser').value;
        if (!toUser) {
            alert("请先指定好友账号，再发起屏幕共享！（注意隐私保护");
            return;
        }
        if (peer == null) {
            WebRTCInit();
        }
        websocket.send(JSON.stringify({
            type: "call_start",
            fromUser: username,
            toUser: toUser,
        }));
    }

    document.getElementById('hangup').onclick = function (e) {
        document.getElementById('toUser').style.visibility = 'unset';
        if (localVideo.srcObject) {
            const videoTracks = localVideo.srcObject.getVideoTracks();
            videoTracks.forEach(videoTrack => {
                videoTrack.stop();
                localVideo.srcObject.removeTrack(videoTrack);
            });
        }
        if (remoteVideo.srcObject) {
            const videoTracks = remoteVideo.srcObject.getVideoTracks();
            videoTracks.forEach(videoTrack => {
                videoTrack.stop();
                remoteVideo.srcObject.removeTrack(videoTrack);
            });
            websocket.send(JSON.stringify({
                type: "hangup",
                fromUser: username,
                toUser: document.getElementById('toUser').value,
            }));
        }
        if (peer) {
            peer.ontrack = null;
            peer.onremovetrack = null;
            peer.onremovestream = null;
            peer.onicecandidate = null;
            peer.oniceconnectionstatechange = null;
            peer.onsignalingstatechange = null;
            peer.onicegatheringstatechange = null;
            peer.onnegotiationneeded = null;
            peer.close();
            peer = null;
        }
        localVideo.srcObject = null;
        remoteVideo.srcObject = null;
    }
}